﻿using Microsoft.AspNetCore.Http;
using Microsoft.Extensions.Logging;
using Newtonsoft.Json.Linq;
using ST.Common.Util;
using ST.Common.Util.Security;
using ST.WX.Common;
using ST.WX.Common.Enums;
using ST.WX.Common.Model;
using ST.WX.XCX.Model;
using ST.WX.XCX.QRCode.Model;
using System;
using System.Collections.Generic;
using System.IO;
using System.Text;
using System.Text.RegularExpressions;

namespace ST.WX.XCX
{
	/// <summary>
	/// 小程序基础相关接口
	/// </summary>
	public class WXXCXBaseApi
	{
		private readonly ILogger logger;
		public WXBaseApi BaseApi { get; }

		public WXXCXBaseApi(ILogger<WXXCXBaseApi> _logger, WXBaseApi _baseApi)
		{
			logger = _logger;
			BaseApi = _baseApi;
		}

		/// <summary>
		/// 小程序登录凭证校验
		/// </summary>
		/// <param name="appid">小程序唯一标识</param>
		/// <param name="js_code">登录时获取的 code</param>
		/// <param name="grant_type"></param>
		/// <returns></returns>
		public WXLoginResult Login(string appID, string appSecret, string jsCode, string grantType = "authorization_code")
		{
			WXLoginResult ret = null;
			try
			{
				if (logger.IsEnabled(LogLevel.Debug))
				{
					logger.LogDebug("登录凭证校验参数->appID：{0}，jsCode：{1}，grantType：{2}", appID, jsCode, grantType);
				}
				if (string.IsNullOrEmpty(appID))
				{
					throw new ArgumentException("appid不能为空");
				}
				string respText = HttpHelper.Get($"https://api.weixin.qq.com/sns/jscode2session?appid={appID}&secret={appSecret}&js_code={jsCode}&grant_type={grantType}");
				if (string.IsNullOrEmpty(respText))
				{
					throw new WXException("登录凭证校验返回为空");
				}
				ret = Newtonsoft.Json.JsonConvert.DeserializeObject<WXLoginResult>(respText);
				if (ret == null)
				{
					throw new WXException("登录凭证校验接口返回为空");
				}
				if (ret.errcode != 0)
				{
					throw new WXException(ret.errmsg, ret.errcode);
				}
				if (string.IsNullOrEmpty(ret.openid))
				{
					throw new WXException("OpenID返回为空");
				}
			}
			catch (WXException ex)
			{
				logger.LogError(ex, "登录凭证校验出错");
				throw ex;
			}
			catch (Exception ex)
			{
				logger.LogError(ex, "登录凭证校验出错");
				throw new WXException("登录凭证校验失败，" + ex.Message);
			}

			return ret;
		}

		public PhoneNumberResult GetPhoneNumber(string appID, string appSecret, string code)
		{
			try
			{
				string respText = HttpHelper.Post("https://api.weixin.qq.com/wxa/business/getuserphonenumber?access_token=" + BaseApi.GetAccessToken(appID, appSecret), paras: "{\"code\":\"" + code + "\"}");
				if (string.IsNullOrEmpty(respText))
				{
					throw new WXException("获取手机号出错结果返回为空");
				}
				PhoneNumberResult ret = Newtonsoft.Json.JsonConvert.DeserializeObject<PhoneNumberResult>(respText);
				if (ret.errcode == 0)
				{
					return ret;
				}
				else
				{
					throw new WXException(ret.errmsg);
				}
			}
			catch (WXException ex)
			{
				logger.LogError(ex, "获取手机号出错");
				throw;
			}
			catch (Exception ex)
			{
				logger.LogError(ex, "获取手机号出错");
				throw new WXException("获取手机号失败，" + (ex.InnerException != null ? ex.InnerException.Message : ex.Message));
			}
		}

		/// <summary>
		/// 微信消息解密
		/// </summary>
		/// <param name="encryptedDataStr"></param>
		/// <param name="iv"></param>
		/// <param name="sessionKey"></param>
		/// <returns></returns>
		public T Decrypt<T>(string encryptedDataStr, string iv, string sessionKey)
		{
			try
			{
				string decryptedDataStr = EncryptHelper.WXAESDecrypt(encryptedDataStr, iv, sessionKey);
				T data = Newtonsoft.Json.JsonConvert.DeserializeObject<T>(decryptedDataStr);
				return data;
			}
			catch (Exception ex)
			{
				logger.LogError(ex, $"微信消息解密出错，加密字符串： {encryptedDataStr} IV： {iv} SessionKey： {sessionKey}");
				throw new WXException("微信消息解密失败，" + ex.Message);
			}
		}

		/// <summary>
		/// 微信消息解密
		/// </summary>
		/// <param name="encryptedDataStr"></param>
		/// <param name="iv"></param>
		/// <param name="sessionKey"></param>
		/// <returns></returns>
		public object Decrypt(string encryptedDataStr, string iv, string sessionKey)
		{
			try
			{
				string decryptedDataStr = EncryptHelper.WXAESDecrypt(encryptedDataStr, iv, sessionKey);
				return Newtonsoft.Json.JsonConvert.DeserializeObject(decryptedDataStr);
			}
			catch (Exception ex)
			{
				logger.LogError(ex, $"微信消息解密出错，加密字符串： {encryptedDataStr} IV： {iv} SessionKey： {sessionKey}");
				throw new WXException("微信消息解密失败，" + ex.Message);
			}
		}
	}
}
